home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
answrbok
/
3_11.lha
/
3_11
/
3_11c.c
< prev
next >
Wrap
Text File
|
1993-08-08
|
3KB
|
152 lines
* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
* The C++ Answer Book */
* Tony Hansen */
* All rights reserved. */
/ Convert a string of signed digits into an integer.
/ Hex and octal prefixes are allowed, as well as
/ character constants.
/ Version 3
define NO_ISODIGIT /* DELETE */
include <ctype.h>
include <limits.h>
include <error.h>
/ convert hexadecimal 0-9, a-f, A-F
/ to its numeric value
nline int hexvalue(char c)
if (isdigit(c))
return c - '0';
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else /* (c >= 'A' && c <= 'F') */
return c - 'A' + 10;
/ return true if c is an octal digit
nline int isodigit(char c)
return isdigit(c) && c < '8';
include "3_11e1.c" /* EXPAND defines TWOSCOMPLEMENT */
nt atoi(const char *s)
char sign = 0;
int i = 0;
switch (*s) // remember the sign
{
case '+':
case '-':
sign = *s++;
break;
}
// for positive numbers on a 2's complement machine,
// the minimum # is -INT_MAX, not INT_MIN
const int int_min = (TWOSCOMPLEMENT && (sign != '-')) ?
(-INT_MAX) : INT_MIN;
switch (*s)
{
case '0': // hex or octal
switch (*++s)
{
case 'x': // hex number
case 'X':
for (s++; isxdigit(*s); s++)
{
if (-i > INT_MAX / 16)
break;
i *= 16;
int n = hexvalue(*s);
if (i < int_min + n)
break;
i -= n;
}
if (isxdigit(*s))
error("integer overflow");
break;
default: // octal number
for ( ; isodigit(*s); s++)
{
if (-i > INT_MAX / 8)
break;
i *= 8;
int n = *s - '0';
if (i < int_min + n)
break;
i -= n;
}
if (isodigit(*s))
error("integer overflow");
break;
}
break;
case '\\': // char constant
if (sign == 0)
{
switch (*++s)
{
case 'x': // \xXXX -> hex
for (int n = 3;
isxdigit(*++s) && n-- > 0;
)
i = i * 16 - hexvalue(*s);
break;
// single character constants
case 'b': i = -'\b'; s++; break;
case 'f': i = -'\f'; s++; break;
case 'n': i = -'\n'; s++; break;
case 'r': i = -'\r'; s++; break;
case 't': i = -'\t'; s++; break;
case 'v': i = -'\v'; s++; break;
case '\\': i = -'\\'; s++; break;
case '\'': i = -'\''; s++; break;
case '"': i = -'\"'; s++; break;
case '0': i = '\0'; s++; break;
default: // \XXX -> octal
for (n = 3;
isodigit(*s) && n-- > 0;
s++)
i = i * 8 - (*s - '0');
break;
}
}
else
error("char constant with sign");
break;
default: // decimal number
for ( ; isdigit(*s); s++)
{
if (-i > INT_MAX / 10)
break;
i *= 10;
int n = *s - '0';
if (i < int_min + n)
break;
i -= n;
}
if (isdigit(*s))
error("integer overflow");
break;
}
if (*s)
error("malformed integer");
return sign == '-' ? i : -i;